package com.example.demo.utils;

import com.example.demo.exception.JwtValidationException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
public class JwtUtils {

//    通过Value获取配置文件中的值
    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long expiration;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final Set<String> BLACKLIST = new HashSet<>();

    /**
     * 生成 Token
     * @param str 用户名
     * @return Token
     */
    public String generateToken(String str) {
        Map<String, Object> claims = new HashMap<>();

        String token = doGenerateToken(claims, str);
        // 将 Token 存储到 Redis 中
        redisTemplate.opsForValue().set(str, token, expiration, TimeUnit.SECONDS);
        return token;
    }

    private String doGenerateToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    /**
     * 验证 Token
     * @param token Token
     * @return 是否有效
     */
    public Boolean validateToken(String token) {
        try {
//            // 检查是否在黑名单中
//            if (BLACKLIST.contains(token)) {
//                return false;
//            }
            Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
            String str = claims.getSubject();

            if (claims == null) {
                throw new JwtValidationException("无效的 JWT 令牌");
            }
            // 从 Redis 中获取存储的 Token
            String storedToken = redisTemplate.opsForValue().get(str);
            return token.equals(storedToken);
//            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 从 Token 中获取用户名
     * @param token Token
     * @return 用户名
     */
    public String getInfoFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
        return claims.getSubject();
    }

    /**
     * 从 Redis 中删除 Token
     * @param username 用户名
     */
    public void deleteTokenFromRedis(String str) {
        redisTemplate.delete(str);
    }


    /**
     * 让 Token 加入黑名单
     * @param token
     */
    public void invalidateToken(String str) {
//        BLACKLIST.add(token);
        deleteTokenFromRedis(str);
    }


}